package jfrederick8;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.awt.image.ImageObserver;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;

/**
 * This class contains instructions on how to draw everything which will every appear on screen
 * 
 * @author John Frederick
 * @version 1.0 - 11 February 2012
 */
public class DrawAll {
	/** This represents the field of play*/
	private Field field;
	/** the list of tiles within the field to be drawn */
	private Tile[][] tiles;
	/** the background image */
	private BufferedImage bg;
	/** the horizontal location of the cursor */
	private int cursorX;
	/** the vertical location of the cursor */
	private int cursorY;
	/** determines when to display the description box on the right */
	private boolean descOnRight;
	
	/**
	 * This constructs the DrawAll object in order to draw everything that will appear on screen
	 * 
	 * @param dist the distributer which allows everything access to all other game objects
	 */
	public DrawAll(Distributer dist){
		try {
			bg = ImageIO.read(new java.io.File("image"+File.separator+"fieldTest.bmp"));
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		field = dist.getField();
		tiles = new Tile[field.getWidth()][field.getHeight()];
		for (int i=0;i<field.getWidth();i++){
			for (int j=0;j<field.getHeight();j++){
				tiles[i][j] = field.getTiles()[i][j];
			}
		}
		cursorX = cursorY = 0;
		descOnRight = true;
	}//end constructor DrawAll
	
	/**
	 * This method directs which objects are to be drawn at a specific moment
	 * 
	 * @param g the display graphics
	 */
	public void drawScreen(Graphics g){
		drawBG(g);
		drawField(g);
		drawOverlay(field.getOverlay(), g);
		drawCursor(g);
		drawBasicDescBox(g);
	}//end method drawScreen
	
	/**
	 * this draws the background image onto the field of play
	 * 
	 * @param g display graphics
	 */
	private void drawBG(Graphics g){
		g.drawImage(bg, 0, 0, null);
	}//end method drawBG
	
	/**
	 * draws the field of play
	 * 
	 * @param g the display graphics
	 */
	private void drawField(Graphics g){
		tiles = field.getTiles();
		for(int i=0;i<tiles.length;i++){
			for(int j=0;j<tiles[0].length;j++){
				drawTile(tiles[i][j], g);
			}
		}
	}//end method draw(Field)
	
	/**
	 * draws each individual tile within the field of play
	 * 
	 * @param tile the tile to be drawn
	 * @param g the display graphics
	 */
	private void drawTile(Tile tile, Graphics g){
		g.setColor(new Color(tile.getEdgeBrightness(),tile.getEdgeBrightness(),tile.getEdgeBrightness(),tile.getEdgeBrightness()));
		g.drawRect(tile.getX() * tile.getWidth(), tile.getY() * tile.getHeight(), tile.getWidth() - 1, tile.getHeight() - 1);
	}//end method drawTile
	
	/**
	 * draws the overlay over the specified tiles
	 * 
	 * @param overlay the lists which determine where the overlay should be drawn
	 * @param g the display graphics
	 */
	private void drawOverlay(int[][] overlay, Graphics g){
		g.setColor(new Color(0, 255, 255, 120));
		for(int i=0;i<overlay.length;i++){
			for(int j=0;j<overlay[0].length;j++){
				if (overlay[i][j] == 1){
					g.fillRect(field.getTiles()[i][j].getX() * field.getTiles()[i][j].getWidth(), field.getTiles()[i][j].getY() * field.getTiles()[i][j].getHeight(), field.getTiles()[i][j].getWidth() - 1, field.getTiles()[i][j].getHeight() - 1);
				}
			}
		}
		g.setColor(Color.WHITE);
		for(int i=0;i<overlay.length;i++){
			for(int j=0;j<overlay[0].length;j++){
				if (overlay[i][j]==1){
					g.drawRect(field.getTiles()[i][j].getX() * field.getTiles()[i][j].getWidth(), field.getTiles()[i][j].getY() * field.getTiles()[i][j].getHeight(), field.getTiles()[i][j].getWidth() - 1, field.getTiles()[i][j].getHeight() - 1);
				}
			}
		}
	}//end method drawOverlay
	
	/**
	 * draws the cursor to indicate the location of the players mouse/active tile
	 * 
	 * @param g the display graphics
	 */
	private void drawCursor(Graphics g){
		g.setColor(Color.YELLOW);
		g.fillRect((cursorX * tiles[cursorX][cursorY].getWidth()) - 2, (cursorY * tiles[cursorX][cursorY].getHeight()) - 2, 5, (tiles[cursorX][cursorY].getHeight()/2) + 2);
		g.fillRect((cursorX * tiles[cursorX][cursorY].getWidth()) - 2, (cursorY * tiles[cursorX][cursorY].getHeight()) + tiles[cursorX][cursorY].getHeight() - 2, (tiles[cursorX][cursorY].getWidth()/2) + 2, 5);
		g.fillRect((cursorX * tiles[cursorX][cursorY].getWidth()) + tiles[cursorX][cursorY].getWidth() - 3, (cursorY * tiles[cursorX][cursorY].getHeight()) + (tiles[cursorX][cursorY].getHeight()/2), 5, (tiles[cursorX][cursorY].getHeight()/2) + 2);
		g.fillRect((cursorX * tiles[cursorX][cursorY].getWidth()) + (tiles[cursorX][cursorY].getWidth()/2), (cursorY * tiles[cursorX][cursorY].getHeight()) - 2, (tiles[cursorX][cursorY].getWidth()/2) + 2, 5);
	}//end method drawCursor
	
	/**
	 * sets the location of the cursor (horizontal)
	 * 
	 * @param x the horizontal location of the mouse (grid number)
	 */
	public void setCursorX(int x){
		this.cursorX = x;
	}//end method setCursorX
	
	/**
	 * sets the location of the cursor (vertical)
	 * 
	 * @param y the vertical location of the mouse (grid number)
	 */
	public void setCursorY(int y){
		this.cursorY = y;
	}//end method setCursorY
	
	/**
	 * draws a basic information box which tells the user about the tile being hovered over. This also changes location to avoid getting in the users way.
	 * 
	 * @param g display graphics
	 */
	private void drawBasicDescBox(Graphics g){
		g.setColor(new Color(100,100,255,200));
		if (descOnRight){
			//bottom right
			g.fillRoundRect(field.getTiles()[0][0].getWidth() * (field.getTiles().length - 5), field.getTiles()[0][0].getHeight() * (field.getTiles()[0].length - 4), 100, 75, 5, 5);
			g.setColor(Color.WHITE);
			g.drawString(field.getTiles()[cursorX][cursorY].getDisplayName(), (field.getTiles()[0][0].getWidth() * (field.getTiles().length - 5)) + 30, (field.getTiles()[0][0].getHeight() * (field.getTiles()[0].length - 4)) + 20);
			g.drawString("Move Cost: " + field.getTiles()[cursorX][cursorY].getWalkWeight(), (field.getTiles()[0][0].getWidth() * (field.getTiles().length - 5)) + 4, (field.getTiles()[0][0].getHeight() * (field.getTiles()[0].length - 3)) + 20);
			g.drawString("Def Bunus: " + (field.getTiles()[cursorX][cursorY].getDefBonus()), (field.getTiles()[0][0].getWidth() * (field.getTiles().length - 5)) + 4, (field.getTiles()[0][0].getHeight() * (field.getTiles()[0].length - 2)) + 20);
			g.setColor(Color.YELLOW);
			g.drawLine(field.getTiles()[0][0].getWidth() * (field.getTiles().length - 5), field.getTiles()[0][0].getHeight() * (field.getTiles()[0].length - 3), field.getTiles()[0][0].getWidth() * (field.getTiles().length - 1), field.getTiles()[0][0].getHeight() * (field.getTiles()[0].length - 3));
		} else {
			//bottom left
			g.fillRoundRect(field.getTiles()[0][0].getWidth(), field.getTiles()[0][0].getHeight() * (field.getTiles()[0].length - 4), 100, 75, 5, 5);
			g.setColor(Color.WHITE);
			g.drawString(field.getTiles()[cursorX][cursorY].getDisplayName(), (field.getTiles()[0][0].getWidth()) + 30, (field.getTiles()[0][0].getHeight() * (field.getTiles()[0].length - 4)) + 20);
			g.drawString("Move Cost: " + field.getTiles()[cursorX][cursorY].getWalkWeight(), field.getTiles()[0][0].getWidth() + 4, field.getTiles()[0][0].getHeight() * (field.getTiles()[0].length - 3) + 20);
			g.drawString("Def Bunus: " + (field.getTiles()[cursorX][cursorY].getDefBonus()), field.getTiles()[0][0].getWidth() + 4, field.getTiles()[0][0].getHeight() * (field.getTiles()[0].length - 2) + 20);
			g.setColor(Color.YELLOW);
			g.drawLine(field.getTiles()[0][0].getWidth(), field.getTiles()[0][0].getHeight() * (field.getTiles()[0].length - 3), field.getTiles()[0][0].getWidth() + 100, field.getTiles()[0][0].getHeight() * (field.getTiles()[0].length - 3));
		}
	}//end method drawBasicDescBox
	
	/**
	 * used to set where the info box should be on the screen
	 * 
	 * @param right true if the info box should be on the right
	 */
	public void setDescOnRight(boolean right){
		descOnRight = right;
	}//end setter setDescOnRight
	
	/**
	 * allows access to determine if the info box is on the right or the left currently
	 * 
	 * @return true if the basic description box is on the right
	 */
	public boolean getDescOnRight(){
		return descOnRight;
	}//end getter descOnRight
}//end class DrawAll
